package com.jdy.haoduoai.view;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.drawable.AnimationDrawable;
import android.util.AttributeSet;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewConfiguration;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.ScrollView;
import android.widget.Scroller;

import com.jdy.haoduoai.util.BasePreference;
import com.jdy.haoduoai.util.Tools;
import com.ycsj.goldmedalnewconcept.R;

import java.text.SimpleDateFormat;
import java.util.Locale;

//import com.jdy.haoduoai.R;

public class RefreshableView extends LinearLayout {
  private View refreshView;
  // private ImageView refreshIndicator;
  // private ProgressBar progressView;
  private ImageView refreshing_icon;
  // private TextView refreshHint;
  // private TextView refreshTimeView;
  // private String downText;
  // private String releaseText;
  private String refreshText;
  private String refreshTimeText;

  private int touchSlop;
  private int refreshMargetTop;
  private final static float MOVEMENT_FACTOR = (float) 0.3;

  private Scroller scroller;
  private RefreshListener refreshListener;
  private boolean isRefreshing = false;
  private boolean isRefreshEnabled = false;

  private static int ARROW_UP = 1;
  private static int ARROW_DOWN = 0;
  private int arrowDirection = 0;
  private Long refreshTime = null;
  private int layoutId = -1;
  private View mScorllableView;
  private boolean isShowRefreshTime = true;

  // 下拉刷新，上次更新
  /**
   * 一分钟的毫秒值，用于判断上次的更新时间
   */
  public static final long ONE_MINUTE = 60 * 1000;

  /**
   * 一小时的毫秒值，用于判断上次的更新时间
   */
  public static final long ONE_HOUR = 60 * ONE_MINUTE;

  /**
   * 一天的毫秒值，用于判断上次的更新时间
   */
  public static final long ONE_DAY = 24 * ONE_HOUR;

  /**
   * 一月的毫秒值，用于判断上次的更新时间
   */
  public static final long ONE_MONTH = 30 * ONE_DAY;

  /**
   * 一年的毫秒值，用于判断上次的更新时间
   */
  public static final long ONE_YEAR = 12 * ONE_MONTH;

  /**
   * 上次更新时间的字符串常量，用于作为SharedPreferences的键值
   */
  private static final String UPDATED_AT = "updated_at";

  /**
   * 上次更新时间的毫秒值
   */
  private long lastUpdateTime;

  /**
   * 为了防止不同界面的下拉刷新在上次更新时间上互相有冲突，使用id来做区分
   */
  private int mId = -1;

  public static final int ID_MAINPAGE = 0; // 首页

  public RefreshableView(Context context, AttributeSet attrs) {
    super(context, attrs);
    if (isInEditMode()) {
      return;
    }
    TypedArray a = context.obtainStyledAttributes(attrs,
        R.styleable.RefreshableView, R.attr.refreshableViewStyle, 0);
    if (a != null) {
      int n = a.getIndexCount();
      for (int i = 0; i < n; i++) {
        int attr = a.getIndex(i);
        switch (attr) {
        case R.styleable.SelectorView_maxVisibleCount:
          layoutId = a.getInteger(attr, -1);
          break;
        }
      }
    }
    if (a != null) {
      a.recycle();
    }
    setLayout(layoutId);
    init();
  }

  /**
   * 是否显示下拉刷新时间
   * 
   * @param bShow
   */
  public void showRefreshTime(boolean bShow) {
    isShowRefreshTime = bShow;
  }

  private AnimationDrawable refreshingAnim;

  private void init() {
    scroller = new Scroller(getContext());

    if (isInEditMode()) {
      return;
    }
    // 隐藏的view
    refreshView = LayoutInflater.from(getContext()).inflate(
        R.layout.refresh_itemxxb, this, false);
    // refreshIndicator = (ImageView) refreshView.findViewById(R.id.indicator);
    // refreshIndicator.setImageResource(R.drawable.icon_refresh_down);
    arrowDirection = ARROW_DOWN;
    // refreshHint = (TextView) refreshView.findViewById(R.id.refresh_hint);
    // refreshTimeView = (TextView) refreshView.findViewById(R.id.refresh_time);
    // refreshTimeView.setVisibility(View.GONE);
    // progressView = (ProgressBar) refreshView.findViewById(R.id.progress);
    refreshing_icon = (ImageView) refreshView
        .findViewById(R.id.refreshing_icon);
    // refreshView.setVisibility(View.INVISIBLE);
    refreshMargetTop = -Tools.getPixelByDip(getContext(), 50);

    LayoutParams params = new LayoutParams(
        LayoutParams.MATCH_PARENT, -refreshMargetTop);
    params.topMargin = refreshMargetTop;
    refreshView.setLayoutParams(params);
    // refreshView.setBackgroundColor(0xff6ac5fe);
    params.gravity = Gravity.CENTER;

    addView(refreshView);
    final ViewConfiguration configuration = ViewConfiguration.get(getContext());
    touchSlop = configuration.getScaledTouchSlop();
    // downText = getContext().getString(R.string.refresh_down_text); // 下拉可以刷新
    // releaseText = getContext().getString(R.string.refresh_release_text); //
    // 松开即可刷新
    refreshText = getContext().getString(R.string.refresh_text); // 正在努力加载中...
    this.setLayoutParams(new LayoutParams(-1, -1));

    refreshing_icon.setBackgroundResource(R.drawable.anim_loading_3);
    refreshingAnim = (AnimationDrawable) refreshing_icon.getBackground();

    // refreshUpdatedAtValue();
  }

  @Override
  protected void onFinishInflate() {
    super.onFinishInflate();
    /*
     * ClassifiedListView view = (ClassifiedListView)
     * this.findViewById(R.id.cinema_listview); if (view == null) {
     * mScorllableView = getFirstScrllabelView(this); } else { mScorllableView =
     * view; }
     */
    mScorllableView = getFirstScrllabelView(this);
    /*
     * if (mScorllableView == null) throw new
     * IllegalArgumentException("can not find a scrollable view in refresh view"
     * );
     */
  }

  public void finishRefresh() {
    LayoutParams params = (LayoutParams) refreshView
        .getLayoutParams();

    BasePreference.getInstance().save(UPDATED_AT + mId,
        System.currentTimeMillis());

    if (params.topMargin > refreshMargetTop) {
      scroller.startScroll(0, params.topMargin, 0, refreshMargetTop
          - params.topMargin);
      this.requestLayout();
      invalidate();
    }
    isRefreshing = false;

    // setBackgroundColor(0xfff1f1f1);
  }

  public boolean isRefreshing() {
    return isRefreshing;
  }

  public void setRefreshEnabled(boolean enabled) {
    isRefreshEnabled = enabled;
  }

  public void setLayout(int layoutId) {
    if (layoutId > 0) {
      this.layoutId = layoutId;
      removeAllViews();
      addView(refreshView);
      View view = LayoutInflater.from(getContext()).inflate(layoutId, null);
      addView(view);
    }
  }

  /**
   * @param refreshTimeText
   *          the refreshTimeText to set
   */
  public void setRefreshTimeText(String refreshTimeText) {
    this.refreshTimeText = refreshTimeText;
    // refreshTimeView.setText(this.refreshTimeText);
  }

  /**
   *          the refreshTimeText to set
   */
  public void setRefreshTime(Long time) {
    SimpleDateFormat format = new SimpleDateFormat("MM-dd HH:mm", Locale.CHINA);
    refreshTimeText = getContext().getString(R.string.last_update_time) + ":";
    refreshTimeText += Tools.getDate(time + "", format);
    // refreshTimeView.setText(refreshTimeText);
    refreshTime = time;
  }

  /**
   * 刷新下拉头中上次更新时间的文字描述。
   */
  @SuppressWarnings("unused")
  private void refreshUpdatedAtValue() {
    lastUpdateTime = BasePreference.getInstance().getLong(UPDATED_AT + mId, -1);
    long currentTime = System.currentTimeMillis();
    long timePassed = currentTime - lastUpdateTime;
    long timeIntoFormat;
    String updateAtValue;
    if (lastUpdateTime == -1) {
      updateAtValue = getResources().getString(R.string.not_updated_yet);
    } else if (timePassed < 0) {
      updateAtValue = getResources().getString(R.string.time_error);
    } else if (timePassed < ONE_MINUTE) {
      updateAtValue = getResources().getString(R.string.updated_just_now);
    } else if (timePassed < ONE_HOUR) {
      timeIntoFormat = timePassed / ONE_MINUTE;
      String value = timeIntoFormat + "分钟";
      updateAtValue = String.format(
          getResources().getString(R.string.updated_at), value);
    } else if (timePassed < ONE_DAY) {
      timeIntoFormat = timePassed / ONE_HOUR;
      String value = timeIntoFormat + "小时";
      updateAtValue = String.format(
          getResources().getString(R.string.updated_at), value);
    } else if (timePassed < ONE_MONTH) {
      timeIntoFormat = timePassed / ONE_DAY;
      String value = timeIntoFormat + "天";
      updateAtValue = String.format(
          getResources().getString(R.string.updated_at), value);
    } else if (timePassed < ONE_YEAR) {
      timeIntoFormat = timePassed / ONE_MONTH;
      String value = timeIntoFormat + "个月";
      updateAtValue = String.format(
          getResources().getString(R.string.updated_at), value);
    } else {
      timeIntoFormat = timePassed / ONE_YEAR;
      String value = timeIntoFormat + "年";
      updateAtValue = String.format(
          getResources().getString(R.string.updated_at), value);
    }

    refreshTimeText = updateAtValue;
    // refreshTimeView.setText(refreshTimeText);
  }

  public void setDownText(String text) {
    // this.downText = text;
  }

  public void setReleaseText(String text) {
    // this.releaseText = text;
  }

  public void setRefreshText(String text) {
    this.refreshText = text;
  }

  private void doMovement(int delta) {
    LayoutParams params = (LayoutParams) refreshView
        .getLayoutParams();
    if (delta > 0) {
      // move down
      params.topMargin += (delta * MOVEMENT_FACTOR);
      refreshView.setLayoutParams(params);
      refreshView.invalidate();

      invalidate();
    } else if (delta < 0) {
      // move up
      if (params.topMargin > refreshMargetTop) {
        params.topMargin += (delta);
        params.topMargin = Math.max(params.topMargin, refreshMargetTop);
        refreshView.setLayoutParams(params);
        refreshView.invalidate();

        invalidate();
      }
    }

    // if (isShowRefreshTime) {
    // refreshTimeView.setVisibility(View.VISIBLE);
    // } else {
    // refreshTimeView.setVisibility(View.GONE);
    // }

    if (refreshTime != null) {
      setRefreshTime(refreshTime);
    }

    // 上次刷新时间
    // refreshUpdatedAtValue();

    // refreshIndicator.setVisibility(View.VISIBLE);

    if (refreshing_icon != null) {
      refreshing_icon.setVisibility(View.GONE);
      refreshing_icon.clearAnimation();

      // setBackgroundColor(0xfff1f1f1);
    }
    if (refreshingAnim != null && refreshingAnim.isRunning()) {
      refreshingAnim.stop();
    }

    if (params.topMargin > 0) {
      // refreshHint.setText(releaseText);
      // refreshIndicator.setImageResource(R.drawable.icon_refresh_up);
      if (arrowDirection != ARROW_UP) {
        // refreshIndicator.setAnimation(AnimationUtils.loadAnimation(
        // getContext(), R.anim.rotate_up));
        arrowDirection = ARROW_UP;
      }
    } else {
      // refreshHint.setText(downText);
      // refreshIndicator.setImageResource(R.drawable.icon_refresh_down);
      if (arrowDirection != ARROW_DOWN) {
        // refreshIndicator.setAnimation(AnimationUtils.loadAnimation(
        // getContext(), R.anim.rotate_down));
        arrowDirection = ARROW_DOWN;
      }
    }
  }

  private boolean canScroll() {
    if (mScorllableView instanceof ScrollView) {
      int scrollY = ((ScrollView) mScorllableView).getScrollY();
      if (scrollY != 0) {
        return true;
      }
    } else if (mScorllableView instanceof ListView) {
      ListView listView = (ListView) mScorllableView;
      if (listView.getChildCount() > 0) {
        View view = listView.getChildAt(0);
        if (Math.abs(view.getTop() - listView.getListPaddingTop()) < 3
            && listView.getFirstVisiblePosition() == 0) {
          // the first child is on the top
          return false;
        } else {
          return true;
        }
      }
    }
    // else if (mScorllableView instanceof ExpandedList) {
    // ExpandedList view = (ExpandedList) mScorllableView;
    // ListView list = view.getListView();
    // if (list.getChildCount() > 0) {
    // View child0 = list.getChildAt(0);
    // if (Math.abs(child0.getTop() - list.getListPaddingTop()) < 3 &&
    // list.getFirstVisiblePosition() == 0) {
    // // the first child is on the top
    // return false;
    // } else {
    // return true;
    // }
    // }
    // }
    // else if (mScorllableView instanceof ClassifiedListView) {
    // ClassifiedListView view = (ClassifiedListView) mScorllableView;
    // ListView list = view.getListView();
    // if (list.getChildCount() > 0) {
    // View child0 = list.getChildAt(0);
    // if (Math.abs(child0.getTop() - list.getListPaddingTop()) < 3 &&
    // list.getFirstVisiblePosition() == 0) {
    // // the first child is on the top
    // return false;
    // } else {
    // return true;
    // }
    // }
    // }
    return false;
  }

  private View getFirstScrllabelView(ViewGroup parent) {
    View result = null;
    if (parent instanceof ScrollView || parent instanceof ListView) {
      return parent;
    } else if (parent.getChildCount() > 0) {
      for (int i = 0; i < parent.getChildCount(); i++) {
        View child = parent.getChildAt(i);

        if (child instanceof ScrollView || child instanceof ListView) {
          result = child;
          break;
        } else if (child instanceof ViewGroup) {
          result = getFirstScrllabelView((ViewGroup) child);
          if (result != null) {
            return result;
          }

        }
      }
    }
    return result;
  }

  public void setTextHintColor(int color) {
    // if (this.refreshHint != null) {
    // refreshHint.setTextColor(color);
    // }
  }

  public void refresh() {
    // refreshIndicator.setImageResource(R.drawable.icon_refresh_down);
    arrowDirection = ARROW_DOWN;

    LayoutParams params = (LayoutParams) refreshView
        .getLayoutParams();
    // refreshIndicator.setVisibility(View.GONE);
    refreshing_icon.setVisibility(View.VISIBLE);

    // setBackgroundColor(0xff25a2f0);

    if (refreshingAnim != null) {
      refreshingAnim.start();
    }

    // refreshTimeView.setVisibility(View.GONE);
    // refreshHint.setText(refreshText);
    scroller.startScroll(0, params.topMargin, 0, 0 - params.topMargin);
    requestLayout();
    invalidate();
    isRefreshing = true;
    if (refreshListener != null) {
      refreshListener.onRefresh(this);
    }
  }

  private void fling() {
    LayoutParams params = (LayoutParams) refreshView
        .getLayoutParams();
    if (params.topMargin > 0) {
      refresh();
    } else if (params.topMargin > refreshMargetTop) {
      scroller.startScroll(0, params.topMargin, 0, refreshMargetTop
          - params.topMargin);
      requestLayout();
      invalidate();
    }

  }

  private int lastY = Integer.MIN_VALUE;
  private int lastX = 0;
  private boolean isBeingDragged = false;

  @Override
  public boolean onInterceptTouchEvent(MotionEvent ev) {
    if (isRefreshing || !isRefreshEnabled) {
      return false;
    }
    final int action = ev.getAction();
    if ((action == MotionEvent.ACTION_MOVE) && (isBeingDragged)) {
      return true;
    }
    LayoutParams params = (LayoutParams) refreshView
        .getLayoutParams();
    int x = (int) ev.getRawX();
    int y = (int) ev.getRawY();

    switch (action) {
    case MotionEvent.ACTION_MOVE:

      final int yDiff = Math.abs(y - lastY);
      final int xDiff = Math.abs(x - lastX);
      if (yDiff < xDiff / 2) {
        return false;
      }

      if (yDiff > touchSlop) {
        isBeingDragged = true;
        if (y - lastY < 0) {
          // move up
          if (params.topMargin <= refreshMargetTop) {
            isBeingDragged = false;
          }
        } else if (y - lastY > 0) {
          // move down
          if (canScroll()) {
            isBeingDragged = false;
          }
        }
      }
      break;
    case MotionEvent.ACTION_DOWN:
      lastY = y;
      lastX = x;
      if (params.topMargin > refreshMargetTop) {
        if (!scroller.isFinished()) {
          scroller.abortAnimation();
        }
        isBeingDragged = true;
      } else {
        isBeingDragged = false;
      }
      break;
    case MotionEvent.ACTION_CANCEL:
    case MotionEvent.ACTION_UP:
      isBeingDragged = false;
      break;
    }
    return isBeingDragged;

  }

  @Override
  public boolean onTouchEvent(MotionEvent ev) {
    super.onTouchEvent(ev);
    int action = ev.getAction();
    int x = (int) ev.getRawX();
    int y = (int) ev.getRawY();
    switch (action) {
    case MotionEvent.ACTION_DOWN:
      lastY = y;
      break;
    case MotionEvent.ACTION_MOVE:

      setBackgroundColor(0xff2bacfc);

      if (lastY != Integer.MIN_VALUE) {
        int delta = y - lastY;
        // move down should be harder than move up, so delta's
        // threshold should not be the same
        int location[] = new int[] { 0, 0 };
        boolean scrollViewContainsXY = true;
        if (mScorllableView != null) {
          mScorllableView.getLocationInWindow(location);
          scrollViewContainsXY = x > mScorllableView.getWidth() - location[0]
              && y < mScorllableView.getHeight() - mScorllableView.getScrollY();
        }

        if ((delta >= 6 || delta < -2)
            && (isBeingDragged || mScorllableView == null
                || !scrollViewContainsXY || mScorllableView.getVisibility() != View.VISIBLE)) {
          doMovement(delta);
          lastY = y;
        }
      } else {
        lastY = y;
      }
      break;
    case MotionEvent.ACTION_CANCEL:
    case MotionEvent.ACTION_UP: {
      fling();
      break;
    }
    }
    return true;
  }

  @Override
  public void computeScroll() {
    if (isInEditMode()) {
      return;
    }
    if (scroller.computeScrollOffset()) {
      int margin = scroller.getCurrY();
      LayoutParams params = (LayoutParams) refreshView
          .getLayoutParams();
      params.topMargin = Math.max(margin, refreshMargetTop);
      refreshView.setLayoutParams(params);
      refreshView.invalidate();
      invalidate();
    }
  }

  public RefreshListener getRefreshListener() {
    return refreshListener;
  }

  public void setRefreshListener(RefreshListener refreshListener) {
    this.refreshListener = refreshListener;
  }

  /**
   * 为了防止不同界面下拉刷新在上次更新时间上互相冲突， 不同界面在注册下拉刷新监听器时一定要传入不同的id。
   * 
   * @param refreshListener
   * @param id
   */
  public void setRefreshListener(RefreshListener refreshListener, int id) {
    this.refreshListener = refreshListener;
    this.mId = id;
  }

  public static interface RefreshListener {
    public void onRefresh(RefreshableView view);
  }

  public static interface Refreshable {
    public boolean canFlickDown();
  }
}
